home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Information
/
CSMP Digest
/
volume 3
/
csmp-digest-v3-130
< prev
next >
Wrap
Text File
|
1996-01-05
|
106KB
|
3,165 lines
C.S.M.P. Digest Fri, 05 Jan 96 Volume 3 : Issue 130
Today's Topics:
Achieving constant frame rates for a game
Async I-O, timer routines, on Power PCs - where documented?
BalloonWriter? Resourcer? or...
Code Compiling on the fly? [PPC]
Creating AE "whose" clause (using formTest) from C?
From FSSpec to DirID
Getting the Highlight color as set in the Color Control Panel?
Help patching NewPtr on PPC?
Is delta copying effective?
NBP Lookups
PICT opcode $9a?
Parameter Block woes
Pixel manipulation
Stupid locked file question
Using Enqueue() and Dequeue() for custom-made queues
[HELP] New to color palettes...simple question!
The Comp.Sys.Mac.Programmer Digest is moderated by Francois Pottier
(pottier@clipper.ens.fr).
The digest is a collection of article threads from the internet
newsgroups comp.sys.mac.programmer.help, csmp.tools, csmp.misc and
csmp.games. It is designed for people who read news semi-regularly and
want an archive of the discussions. If you don't know what a
newsgroup is, you probably don't have access to it. Ask your systems
administrator(s) for details. If you don't have access to news, you
may still be able to post messages to the group by using a mail server
like anon.penet.fi (mail help@anon.penet.fi for more information).
Each issue of the digest contains one or more sets of articles (called
threads), with each set corresponding to a 'discussion' of a particular
subject. The articles are not edited; all articles included in this digest
are in their original posted form (as received by our news server at
nef.ens.fr). Article threads are not added to the digest until the last
article added to the thread is at least two weeks old (this is to ensure that
the thread is dead before adding it to the digest). Article threads that
consist of only one message are generally not included in the digest.
The digest is officially distributed by two means, by email and ftp.
If you want to receive the digest by mail, send email to listserv@ens.fr
with no subject and one of the following commands as body:
help Sends you a summary of commands
subscribe csmp-digest Your Name Adds you to the mailing list
signoff csmp-digest Removes you from the list
Once you have subscribed, you will automatically receive each new
issue as it is created.
The official ftp info is ftp://ftp.dartmouth.edu/pub/csmp-digest.
Questions related to the ftp site should be directed to
scott.silver@dartmouth.edu.
-------------------------------------------------------
>From joel@phantom.itg.ti.com (Joel Quejada)
Subject: Achieving constant frame rates for a game
Date: 18 Dec 1995 18:05:20 GMT
Organization: Texas Instruments, Inc.
I am writing a game in which I would like a constant frame rate throughout.
I also would like the game to take advantage of faster machines, by making
the sprite movements smaller. The end result should be smoother animation
on faster machines. The game compensates on slower machines by moving the
sprite in larger increments.
In the beginning of my game, I run a benchmark that checks to see what
frame rate can be achieved by a system when the maximum number of
sprites are active on the screen. I then peg the frame rate of the game
at this number. This frame rate is also used to pre-calculate a table
that specifies how much to move a sprite assuming this frame rate.
This seems to work great. I have a constant frame rate, regardless of
how many sprites are on screen, and sprites move at the "same speed"
regardless of what the frame rate is. My benchmark runs for a couple of
seconds in order to get a good fps reading.
My question: is this what is done by other games? Is there an easier
way of determining from the processor type and speed how much fps a
given machine can achieve?
Thanks,
Joel
+++++++++++++++++++++++++++
>From phixus@deltanet.com (Chris De Salvo)
Date: Tue, 19 Dec 1995 00:11:23 -0800
Organization: MacPlay
In article <4b4ah0$p2l@dsk92.itg.ti.com>, joel@phantom.itg.ti.com (Joel
Quejada) wrote:
>My question: is this what is done by other games? Is there an easier
>way of determining from the processor type and speed how much fps a
>given machine can achieve?
One simple method would be to either use the Microseconds() trap or a Time
Manager task to keep track of real-time for you. Then, you could monitor
your frame-rate against the real-time clock. Doing this you can then
dynamically adjust your deltas. When you're going too slow, start moving
more. When you're going too fast start moving less.
This could be useful in cases where you often have big shifts in the
number of things you're moving on screen.
L8R
Chris
--
phixus@deltanet.com | Macintosh: Changing the world,
Chris De Salvo | one person at a time!
Professional Mac Geek | -----------------------------
for MacPlay, Inc. | (I wish they'd hurry up!)
http://www.deltanet.com/users/phixus
+++++++++++++++++++++++++++
>From Jacques.Menu@hospvd.ch (Jacques MENU)
Date: Wed, 20 Dec 1995 10:30:00 -0800
Organization: OIH - SHC
Hi Joel,
> My question: is this what is done by other games? Is there an easier
> way of determining from the processor type and speed how much fps a
> given machine can achieve?
I'm no game writer myself, by I had the same problem long time ago, which
I solved in the following way : instances of class TTiming can be sent
messages to let time elapse for a given number of milliseconds or 1e-4
secs.
The idea is to sample a large number of iterations on nothing on the
current machine, and to compare the time taken with a reference machine,
which happens to be a good old Mac II.
Measures on a datascope show that when asking for a 25 ms delay, I
actually usually get 24, that is, a 4% error.
Though this is based essentially on integer arithmetic, I guess you coud
do much the same with floating numbers.
Enjoy !
// •------------------------------------------------------------------------
// UTiming.h
// Copyright 1992 by JMI. All rights reserved.
// •------------------------------------------------------------------------
#ifndef __UTiming__
#define __UTiming__
#include <stream.h>
class TTiming
{
public:
TTiming (long samplingIterations = 500000);
// roughly 0.5 sec on a Mac II
void MilliSecsDelay (long theMilliSecsDelay);
void Ten4SecsDelay (long theTen4SecsDelay);
void Report (ostream & theStream);
static void SampleTiming (ostream & theStream);
private:
long fMilliSecIterations;
// the result of sampling the current machine
float fMachineSpeedFactor;
// used to characterize various machine speeds
long fSamplingIterations;
float fSamplingDuration;
}; // TTiming
#endif __UTiming__
// •------------------------------------------------------------------------
// UTiming.cp
// Copyright 1992 by JMI. All rights reserved.
// •------------------------------------------------------------------------
#pragma segment Timing
#ifndef __UTiming__
#include "UTiming.h"
#endif
// Idea: determine how many times to iterate over a NOP to attain 1 ms
// 1 tick = 1/60 sec = 16.67 ms = 50/3 ms, hence 1 ms = 3/50 tick
const long kReferenceIterations = 40000000;
// roughly 10.0 secs on a Mac II fx
const float kReferenceDuration = 10.1667;
// the exact duration of "kReferenceIterations" on a Mac II fx
const float kSpeedFactorCorrection = 0.9525;
// the value of fMachineSpeedFactor on the reference machine
// is not exactly equal to 1.0!
// •------------------------------------------------------------------------
TTiming :: TTiming (long samplingIterations)
{
long startTicks, endTicks;
startTicks = TickCount ();
for (long counter = 1; counter <= samplingIterations; ++ counter)
; // NOTHING
endTicks = TickCount ();
fSamplingIterations = samplingIterations;
fSamplingDuration = (endTicks - startTicks) / 60.0;
fMilliSecIterations =
long (
samplingIterations / fSamplingDuration /
1000.0 / kSpeedFactorCorrection );
fMachineSpeedFactor =
// smaller than 1.0 for machines slower than the reference
(samplingIterations / fSamplingDuration)
/
(kReferenceIterations / kReferenceDuration);
} // TTiming :: TTiming
// •------------------------------------------------------------------------
void TTiming :: Report (ostream & theStream)
{
theStream <<
"TTiming :: Report ()\n" <<
" kSpeedFactorCorrection = " << kSpeedFactorCorrection << "\n" <<
" fMachineSpeedFactor = " << fMachineSpeedFactor << "\n" <<
" fMilliSecIterations = " << fMilliSecIterations << "\n" <<
" fSamplingIterations = " << fSamplingIterations << "\n" <<
" fSamplingDuration = " << fSamplingDuration << "\n\n";
theStream <<
"On the reference machine, 'fMachineSpeedFactor' above gives\n"
"the adequate value of 'kSpeedFactorCorrection'!\n\n";
theStream . flush ();
} // TTiming :: Report
void TTiming :: MilliSecsDelay (long theMilliSecsDelay)
{
const long limit =
theMilliSecsDelay * fMilliSecIterations;
for (long counter = 1; counter <= limit; ++ counter)
; // NOTHING
} // TTiming :: MilliSecsDelay
void TTiming :: Ten4SecsDelay (long theTen4SecsDelay)
// used to obtain tenth's of a milli-second delays
{
const long limit =
long (theTen4SecsDelay * fMilliSecIterations / 10.0);
for (long counter = 1; counter <= limit; ++ counter)
; // NOTHING
} // TTiming :: Ten4SecsDelay
// •------------------------------------------------------------------------
void TTiming :: SampleTiming (ostream & theStream)
// used to tune "kReferenceDuration"
{
const float kDesiredDuration = 10.0; // secs
TTiming theTiming;
long startTicks, endTicks;
float actualDuration, error;
theTiming.Report (theStream);
theStream <<
"*** Let's start looping " << kReferenceIterations << " times ! ***\n\n";
theStream . flush ();
startTicks = TickCount ();
for (long counter = 1; counter <= kReferenceIterations; ++ counter)
; // NOTHING
endTicks = TickCount ();
actualDuration = (endTicks - startTicks) / 60.0;
error = 100 * (actualDuration - kReferenceDuration) / kReferenceDuration;
theStream <<
"kReferenceIterations = " << kReferenceIterations << "\n" <<
"kReferenceDuration = " << kReferenceDuration << "\n" <<
"actualDuration = " << actualDuration << " secs.\n" <<
"error = " << error << " %\n\n";
theStream << "\n0 sec." << "\n";
theStream . flush ();
SysBeep (1);
startTicks = TickCount ();
theTiming.MilliSecsDelay (long (kDesiredDuration * 1000));
endTicks = TickCount ();
SysBeep (1);
actualDuration = (endTicks - startTicks) / 60.0;
error = 100.0 * (actualDuration - kDesiredDuration) / kDesiredDuration;
theStream <<
"kDesiredDuration = " << kDesiredDuration << " secs.\n" <<
"actualDuration = " << actualDuration << " secs.\n" <<
"error = " << error << " %\n\n";
theStream << "\n*** That's all folks! ***" << "\n\n";
theStream . flush ();
} // TTiming :: SampleTiming
// •------------------------------------------------------------------------
--
Jacques Menu
Office Informatique
Service des Hospices Cantonaux
1011 - Lausanne
Switzerland
+++++++++++++++++++++++++++
>From rickgenter@aol.com (RickGenter)
Date: 20 Dec 1995 09:12:41 -0500
Organization: America Online, Inc. (1-800-827-6364)
>>>
My question: is this what is done by other games? Is there an easier
way of determining from the processor type and speed how much fps a
given machine can achieve?
<<<
For IndyCar Racing II, we monitor the frame rate and adjust graphics
detail accordingly. We don't aim for a constant frame rate, but we let the
user choose what they want for a minimum/maximum frame rate. If the frame
rate exceeds the maximum, we turn on more detail. If the frame rate drops
below minimum, we turn off some detail.
Rick Genter
Technical Lead, IndyCar Racing II
Papyrus Design Group, Inc.
---------------------------
>From nagle@netcom.com (John Nagle)
Subject: Async I-O, timer routines, on Power PCs - where documented?
Date: Tue, 19 Dec 1995 07:13:08 GMT
Organization: NETCOM On-line Communication Services (408 261-4700 guest)
There are a few system calls, such as I/O completion routines and
Time Manager routines, that have calling sequences which use specific
68K registers. Obviously it's different on PowerPCs. But where are
the PPC interfaces documented? IM (both paper and CD-ROM) is out of
date, and "PowerPC System Software" doesn't help. Anybody know?
Thanks.
John Nagle
+++++++++++++++++++++++++++
>From wysocki@netcom.com (Chris Wysocki)
Date: Tue, 19 Dec 1995 17:14:32 GMT
Organization: NETCOM On-line Communication Services (408 261-4700 guest)
In article <nagleDJto1w.L4r@netcom.com>, John Nagle <nagle@netcom.com> wrote:
> There are a few system calls, such as I/O completion routines and
>Time Manager routines, that have calling sequences which use specific
>68K registers. Obviously it's different on PowerPCs. But where are
>the PPC interfaces documented? IM (both paper and CD-ROM) is out of
>date, and "PowerPC System Software" doesn't help. Anybody know?
>Thanks.
Look at the uppXXXXProcInfo constants and the CallXXXXProc macros in
the header files to determine how the 68K register parameters are
passed to the PowerPC routines. Since PowerPC uses a uniform set of
calling conventions, the 68K register parameters will be passed to the
routine as formal arguments, so a 68K I/O completion routine that
looks like:
void IOCompletion68K(void)
{
ParmBlkPtr pb = (ParmBlkPtr) GetA0();
/*...*/
}
would be declared for PowerPC as:
void IOCompletionPPC(ParmBlkPtr pb)
{
/*...*/
}
Chris.
---------------------------
>From mgrueter@aol.com (M Grueter)
Subject: BalloonWriter? Resourcer? or...
Date: 14 Dec 1995 20:25:40 -0500
Organization: America Online, Inc. (1-800-827-6364)
I need to create some Balloon Help for my app. IM Help Manager talks in
several places about BalloonWriter from APDA. I called APDA, and was told
they no longer sell this product. Where can I get a copy? Is Resourcer
better (easier) to do this with?
- Mike
+++++++++++++++++++++++++++
>From ckt@best.com (Chris Thomas)
Date: Thu, 14 Dec 1995 20:34:49 -0800
Organization: Echo Software
In article <4aqiqk$5vb@newsbf02.news.aol.com>, mgrueter@aol.com (M
Grueter) wrote:
> I need to create some Balloon Help for my app. IM Help Manager talks in
> several places about BalloonWriter from APDA. I called APDA, and was told
> they no longer sell this product. Where can I get a copy? Is Resourcer
> better (easier) to do this with?
To be perfectly honest, the easiest way to do Balloon Help is Rez.
Resorcerer can do it, though. BalloonWriter doesn't work.
--
Chris Thomas, ckt@best.com
+++++++++++++++++++++++++++
>From andyb@oasis.novia.net (Andy Bachorski)
Date: Fri, 15 Dec 1995 09:51:34 -0600
Organization: HardCopy, Inc.
In article <4aqiqk$5vb@newsbf02.news.aol.com>, mgrueter@aol.com (M
Grueter) wrote:
> I need to create some Balloon Help for my app. IM Help Manager talks in
> several places about BalloonWriter from APDA. I called APDA, and was told
> they no longer sell this product. Where can I get a copy? Is Resourcer
> better (easier) to do this with?
If you are using CodeWarrior, there is a freeware balloon help compiler
available, written by Tim Enders. You can find it on metrowerks site
<http://www.metrowerks.com>.
Andy B
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Andy Bachorski * HardCopy, Inc. * andyb@oasis.novia.net
+++++++++++++++++++++++++++
>From munz@wordperfect.com (Mark Munz)
Date: Fri, 15 Dec 1995 10:08:55 -0700
Organization: (none)
In article <4aqiqk$5vb@newsbf02.news.aol.com>, mgrueter@aol.com (M
Grueter) wrote:
> I need to create some Balloon Help for my app. IM Help Manager talks in
> several places about BalloonWriter from APDA. I called APDA, and was told
> they no longer sell this product. Where can I get a copy? Is Resourcer
> better (easier) to do this with?
>
> - Mike
I've found Resourcer's templates easy enough to work with. I use it to
write any balloon help I require. Just my $0.02 worth.
Mark Munz
+++++++++++++++++++++++++++
>From ingemar@lysator.liu.se (Ingemar Ragnemalm)
Date: 17 Dec 1995 10:01:23 GMT
Organization: (none)
ckt@best.com (Chris Thomas) writes:
>In article <4aqiqk$5vb@newsbf02.news.aol.com>, mgrueter@aol.com (M
>Grueter) wrote:
>> I need to create some Balloon Help for my app. IM Help Manager talks in
>> several places about BalloonWriter from APDA. I called APDA, and was told
>> they no longer sell this product. Where can I get a copy? Is Resourcer
>> better (easier) to do this with?
>To be perfectly honest, the easiest way to do Balloon Help is Rez.
>Resorcerer can do it, though. BalloonWriter doesn't work.
BalloonWriter works. It isn't the most bug-free software I've seen, but
it definitely works, and I think it is pretty good for hacking in a few
balloons quickly.
--
- -
Ingemar Ragnemalm, PhD
Image processing, Mac shareware games
E-mail address: ingemar@isy.liu.se or ingemar@lysator.liu.se
+++++++++++++++++++++++++++
>From ckt@best.com (Chris Thomas)
Date: Wed, 20 Dec 1995 20:55:33 -0800
Organization: Echo Software
In article <4b0ppk$nb4@newsy.ifm.liu.se>, ingemar@lysator.liu.se (Ingemar
Ragnemalm) wrote:
> ckt@best.com (Chris Thomas) writes:
>
> >In article <4aqiqk$5vb@newsbf02.news.aol.com>, mgrueter@aol.com (M
> >Grueter) wrote:
>
> >> I need to create some Balloon Help for my app. IM Help Manager talks in
> >> several places about BalloonWriter from APDA. I called APDA, and was told
> >> they no longer sell this product. Where can I get a copy? Is Resourcer
> >> better (easier) to do this with?
>
> >To be perfectly honest, the easiest way to do Balloon Help is Rez.
> >Resorcerer can do it, though. BalloonWriter doesn't work.
>
> BalloonWriter works. It isn't the most bug-free software I've seen, but
> it definitely works, and I think it is pretty good for hacking in a few
> balloons quickly.
Wait a minute, now. BalloonWriter *doesn't* work on my PowerMac 7100.
--
Chris Thomas, ckt@best.com
---------------------------
>From kaw11@cornell.edu (Kevin A. Walsh)
Subject: Code Compiling on the fly? [PPC]
Date: 17 Dec 1995 19:48:14 GMT
Organization: Cornell University
Hi,
I was wondering if this could be done:
I want to implement a very small compiler into a program. The compiler
would not do much other than just mathematical formulas, and maybe some
very simple branches or something. Anyway, the resulting code from these
short programs would be very standardized, so the compiler would be fairly
easy to write.
Now, once i have the compiled PPC code, say in an array of longs or
something, is it possible to cast this to a function, and call it durring
runtime?
I have read somewhere (IM maybe) that with VM, Instruction Memory is read
only. But, this does not really specifically prohibit writing code, and
then transforming it into a read only Instruction Memory. hmmm....
The result would be that you type in a simple expression
(algebra/trig/...) using a standard form (ie, predefined variables x,y,z
or something). The program compiles this to a short sequence of PPC
instructions in an array of longs. Then, you can just call this repeatedly
to iterate the function. This would in effect be like having built in
support for all possible simple functions, because there would be no extra
overhead once you go going!
So, imposible or what?
Thanks,
-kev
(email also please... kaw11@cornell.edu)
+++++++++++++++++++++++++++
>From "Andrew C. Plotkin" <erkyrath+@CMU.EDU>
Date: Sun, 17 Dec 1995 19:13:25 -0500
Organization: Carnegie Mellon, Pittsburgh, PA
kaw11@cornell.edu (Kevin A. Walsh) writes:
> I want to implement a very small compiler into a program. The compiler
> would not do much other than just mathematical formulas, and maybe some
> very simple branches or something. Anyway, the resulting code from these
> short programs would be very standardized, so the compiler would be fairly
> easy to write.
>
> Now, once i have the compiled PPC code, say in an array of longs or
> something, is it possible to cast this to a function, and call it durring
> runtime?
Sure. You'd want to flush the caches (data and instruction) before you
called it. And obviously you'd have to use the same calling convention
as your compiler, but that should be in the compiler docs somewhere.
> I have read somewhere (IM maybe) that with VM, Instruction Memory is read
> only. But, this does not really specifically prohibit writing code, and
> then transforming it into a read only Instruction Memory. hmmm....
You can't transform writable memory into into read-only memory (or, at
least, it's not necessary.) You'd be calling the code in writable
memory. There's nothing wrong with this, as long as you flush caches.
--Z
"And Aholibamah bare Jeush, and Jaalam, and Korah: these were the borogoves..."
+++++++++++++++++++++++++++
>From tim@apple.com (Tim Olson)
Date: 20 Dec 1995 16:08:01 GMT
Organization: Apple Computer, Inc. / Somerset
In article <kaw11-1712951450030001@132.236.178.23>
kaw11@cornell.edu (Kevin A. Walsh) writes:
> Now, once i have the compiled PPC code, say in an array of longs or
> something, is it possible to cast this to a function, and call it durring
> runtime?
Yes. However, before you try to execute it, you must make sure the
processor's instruction and data caches are coherent. There is a
system routine called "MakeDataExecutable" (or something like that)
which you should call to do this.
-- Tim Olson
Apple Computer, Inc. / Somerset
tim@apple.com
+++++++++++++++++++++++++++
>From chanson@mcs.com (Chris Hanson)
Date: Fri, 22 Dec 1995 22:59:08 -0600
Organization: MCSNet Internet Services
In article <Ekp=8Zm00WB7M9bn5H@andrew.cmu.edu>, "Andrew C. Plotkin"
<erkyrath+@CMU.EDU> wrote:
>Sure. You'd want to flush the caches (data and instruction) before you
>called it. And obviously you'd have to use the same calling convention
>as your compiler, but that should be in the compiler docs somewhere.
Actually, it's in Inside Macintosh: PowerPC System Software. But yeah.
Also, y'all might want to check out the latest release of PowerLisp (at
<http://www.crl.com:80/~rgcorman/>) -- it's got a PowerPC assembler and
compiler in Common Lisp source code. Pretty cool.
TTFN,
Chris
PS - Hi Zarf!
- -
chanson@mcs.com (Chris Hanson, KSC)
"I always find my self wondering how people who can't code manage to
get through life." -Steve Gifford
---------------------------
>From kriegsman@tr.org (Mark Kriegsman)
Subject: Creating AE "whose" clause (using formTest) from C?
Date: Thu, 14 Dec 1995 11:56:59 -0500
Organization: The Internet Access Company
Summary:
Has anyone every actually written code that create AE object specifiers
that use the formTest / typeObjectBeingExamined business in C or C++?
I've read IM Interapplication Communication from cover to cover, and
in general I'm a patient person and I sometimes have a clue; but somebody
has decided that this week it's my turn to go nuts for a little while...
I'm converting an applescript widget to C, and I've got everything else
working fine EXCEPT for the "whose" clause, which IMIAC describes in some
detail as using the formTest / typeObjectBeingExamined coupling. I think
I'm doing it just like the book shows (don't we all think this?), but I
just can't get back any useful result from the target app.
In AppleScript, the code says:
tell application "FileMaker Pro"
set matchedRecords to every Record of Database "people database"
whose Cell "lastname" contains "kriegsman"
end tell
I can send AEs to FMP just fine, thanks, and the results come back
beautifully -- unless I try to compose a "whose" clause (formTest /
typeObjectBeingExamined). I just can't seem a compose a "whose" clause
that actually works.
I think I'm confused about the nesting of the 'exmn' descriptor
inside the object specifier, and I can't even find one single example of
actual C code that uses an 'exmn' descriptor anywhere on the net, on the
CodeWarrior CDs, on the Apprentice CD, or pretty much anywhere at all.
So, have you even done this or seen it done, and can you share some insights?
Please drop me a note at kriegsman@tr.org and/or post to the group if it
seems appropriate.
Thanks very much...
-Mark
--
Mark Kriegsman
kriegsman@tr.org
http://www.tr.org/users/mek/
+++++++++++++++++++++++++++
>From andyb@oasis.novia.net (Andy Bachorski)
Date: Thu, 14 Dec 1995 17:00:29 -0600
Organization: HardCopy, Inc.
In article <kriegsman-1412951156590001@www.tr.org>, kriegsman@tr.org (Mark
Kriegsman) wrote:
> Has anyone every actually written code that create AE object specifiers
> that use the formTest / typeObjectBeingExamined business in C or C++?
>... snip ....
> So, have you even done this or seen it done, and can you share some insights?
>
> Please drop me a note at kriegsman@tr.org and/or post to the group if it
> seems appropriate.
Mark,
There's an article in the latest develop magazine (vol 24) that covers how
to handle a whose clause in an app. Don't know if it will have what you're
looking for, as I've not read it yet.
Andy B
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Andy Bachorski * HardCopy, Inc. * andyb@oasis.novia.net
+++++++++++++++++++++++++++
>From bc@wetware.com (bill coderre)
Date: Thu, 14 Dec 1995 19:25:22 -0800
Organization: GRAFIX::CODERRE
kriegsman@tr.org (Mark Kriegsman) wrote:
| Summary:
| Has anyone every actually written code that create AE object specifiers
| that use the formTest / typeObjectBeingExamined business in C or C++?
Funny how this works.
_develop_ 24, just out, has this as the topic of its lead article.
If you aren't already reading that article, well, you should drop
everything and get it.
bc
+++++++++++++++++++++++++++
>From gwatts@fnal.fnal.gov (Gordon Watts)
Date: Thu, 14 Dec 1995 23:06:12 -0600
Organization: Brown University
In article <kriegsman-1412951156590001@www.tr.org>, kriegsman@tr.org (Mark
Kriegsman) wrote:
>Summary:
>
> Has anyone every actually written code that create AE object specifiers
> that use the formTest / typeObjectBeingExamined business in C or C++?
>
>
>I've read IM Interapplication Communication from cover to cover, and
>in general I'm a patient person and I sometimes have a clue; but somebody
>has decided that this week it's my turn to go nuts for a little while...
I seem to get more than my share of those weeks. :-) I recently had
trouble with the Get Data apple event (!). There are several tools around
that can help you out. One is AETracker -- it is in the tool chest on the
apple server (I down loaded the thing just recently). It will trap
*every* damm call made to the ae manager. I told it to give me lots of
info from the script editor, and then ran my script with the "get data" in
it. I could see most of the descriptors being built and was able to
figure out what I was doing wrong.
I'm not sure how useful it will be for a complex apple event like the one
you describe, but it might give you that one "clue" you've been missing
(search the log file for the typeObjectBeingExamined characters...).
I've also heard of a tool that will trap every apple event that goes back
and forth (via the recording feature) and do a text dump of all the
descriptors and data in the event. I can't remember the name, or where I
read about it. But that would be ideal in this case, as it would show you
the exact nesting that the script editor used. Perhaps someone will read
this and recall (or Jon Pugh (sp?) will know?).
Good luck.
Cheers,
Gordon.
--
gwatts@fnal.fnal.gov
+++++++++++++++++++++++++++
>From aznemeng@godzilla.zeta.org.au (Andrew Nemeth)
Date: 15 Dec 1995 07:13:28 GMT
Organization: Kralizec Dialup Unix
Mark Kriegsman (kriegsman@tr.org) wrote:
: Summary:
: I'm converting an applescript widget to C, and I've got everything else
: working fine EXCEPT for the "whose" clause, which IMIAC describes in some
: detail as using the formTest / typeObjectBeingExamined coupling. I think
: I'm doing it just like the book shows (don't we all think this?), but I
: just can't get back any useful result from the target app.
: In AppleScript, the code says:
: tell application "FileMaker Pro"
: set matchedRecords to every Record of Database "people database"
: whose Cell "lastname" contains "kriegsman"
: end tell
For such complicated AE activity, programming via the OSL is a self-
defeating activity. You could do it, but the code you will end up
writing will be so convoluted that it would be almost impossible to
maintain and upgrade.
Only use the OSL for 'simple' AE stuff, and not to replace great
swathes of activity which should really be performed in AppleScript.
Presumably you want to convert to C/OSL in order to increase runtime speed.
Take a look at my 'OSA_Runner.sit.hqx' code at info-mac/dev/src (or my
home page at 'http://www.zeta.org.au/~aznemeng') to show how to run
Applescripts (fast!) from within applications, with or without variables
supplied at run time.
Don't be put off by AppleScript. Provided you 'tweak' it the right way,
the run-time speed is only slightly slower than direct OSL calls - without
the heartache.
Andrew Nemeth
http://www.zeta.org.au/~aznemeng
"Team Players are Corporate Moonies"
+++++++++++++++++++++++++++
>From pottier@drakkar.ens.fr (Francois Pottier)
Date: 15 Dec 1995 12:56:58 GMT
Organization: Ecole Normale Superieure, Paris
In article <kriegsman-1412951156590001@www.tr.org>,
Mark Kriegsman <kriegsman@tr.org> wrote:
> Has anyone every actually written code that create AE object specifiers
> that use the formTest / typeObjectBeingExamined business in C or C++?
I have done it inside my own application (it supports "whose" clauses and
is recordable, so it has to build these events and send them to itself).
Unfortunately, I don't have my code at hand, but here's a piece of advice
which might be useful. Instead of sending your events to FileMaker Pro,
send them to your own app and turn recording on. This way, your events
will be recorded and you will be able to use the Script Editor to see what
they look like in human-readable form.
I hope this helps,
--
Francois
pottier@dmi.ens.fr
http://www.eleves.ens.fr:8080/home/pottier/
+++++++++++++++++++++++++++
>From monhacker@aol.com (MonHacker)
Date: 15 Dec 1995 09:26:54 -0500
Organization: America Online, Inc. (1-800-827-6364)
In article <kriegsman-1412951156590001@www.tr.org>, kriegsman@tr.org (Mark
Kriegsman) wrote:
>Summary:
>
> Has anyone every actually written code that create AE object
specifiers
> that use the formTest / typeObjectBeingExamined business in C or C++?
>
>
>I've read IM Interapplication Communication from cover to cover, and
>in general I'm a patient person and I sometimes have a clue; but somebody
>has decided that this week it's my turn to go nuts for a little while...
Mark,
You may want to consider using AEGizmos. When I get a compex AE the first
thing I do is send it from Script Editor or Scripter and then use the
AEPrint function inside the application to see what it looks like (in all
it's glory). Later, when I want to recreate such a beast, I just turn
that same AEGizmo string loose on the AEBuild function and ... bingo - I
have the AE in it's correct form. One note of caution - there may be a
bug in the AEPrint function ... when you run with QC it is detecting a
'write past end of block' condition. Someday I'll have to dig into this a
little deeper.
Good Luck,
Bob Boylan
+++++++++++++++++++++++++++
>From andyb@oasis.novia.net (Andy Bachorski)
Date: Fri, 15 Dec 1995 09:46:56 -0600
Organization: HardCopy, Inc.
In article <kriegsman-1412951156590001@www.tr.org>, kriegsman@tr.org (Mark
Kriegsman) wrote:
>Summary:
>
> Has anyone every actually written code that create AE object specifiers
> that use the formTest / typeObjectBeingExamined business in C or C++?
>
>
>I've read IM Interapplication Communication from cover to cover, and
>in general I'm a patient person and I sometimes have a clue; but somebody
>has decided that this week it's my turn to go nuts for a little while...
Upon further reflection, why not just include the script itself in your
app. You said that you have an equivalent AppleScript working already.
There is an article in one of the more recent MacTech magazines (sorry,
don't remember which one) that shows a technique for embeding scripts in
an app. There is also a new script compiler for CodeWarrior that was
released by Gordon Watts <gwatts@fnal.fnal.gov>. Here is the text from the
announcement. It sounds like what you are looking for.
... Just noticed he (Gordon) replied to your question as well. Wonder why
he didn't mention this?
Andy B
=-=-=-=-=-=-=
From: gwatts@fnal.fnal.gov (Gordon Watts)
Newsgroups: comp.sys.mac.programmer.codewarrior
Subject: Script Builder 1.0
Date: Wed, 13 Dec 1995 13:36:34 -0500
Organization: Brown University
Lines: 43
Message-ID: <gwatts-1312951336340001@128.148.60.219>
NNTP-Posting-Host: 128.148.60.219
Hi,
Script Builder 1.0 is a free (small) plugin compiler for the CW7
environment that allows you to add compiled scripts (from the script
editor) to your project.
I've been trying to see the light, and integrate applescript more
closely with my applications. One thing I really hate writeing is the
choose document and send an apple event to open document code. As long as
you don't need any thing fancy in the way of dialog boxes, you can do it
in apple script in a few lines.
Cool -- but I don't want this script to be a seperate file that sits in
the application folder -- I want it to be a resource in my app. Script
editor will compile scripts into a resource and has a nice interface, so I
leaveraged off of that, and wrote this small plug in that will allow you
to add compiled scripts to your project. You must make a minor change to
your script and add a comment line containing a tag that has the resource
id number, but other than that, scripts can remain the same.
I've also included a few classes I use to help me access these scripts
in my projects (pp projects, btw). These objects take care of connecting
to a default script component, loading the script from a named resource,
and executing it (ignoring or returning AEDesc results). They will throw
expections. They have not, however, been carefully tested, so take care.
All sample code is C++, but I'm more than happy to add pascal (or anything
else) to the archive if people will send me the snippits.
There is a readme file included with installation instructions and a
show example of how to use the thing. Let me know if there are any
problems (gwatts@fnal.fnal.gov). Good luck.
Oh -- I have submitted this to info-mac and other sites. I suspect it
will appear today or tomorrow in the /dev area as script-builder-10...
wait, let me check... no, it dosn't seem to be there yet. I can't be sure
of the name: Igor will name it (perhaps later today). I've also sent it
off to the metrowerks class library, but it isn't a class, so I'm not sure
if it will be included in that (I did that about 10 minutes ago).
Cheers,
Gordon.
--
gwatts@fnal.fnal.gov
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Andy Bachorski * HardCopy, Inc. * andyb@oasis.novia.net
+++++++++++++++++++++++++++
>From ck@be.com (C.K. Haun)
Date: Fri, 15 Dec 1995 10:11:36 -0800
Organization: Be, Inc.
In article <kriegsman-1412951156590001@www.tr.org>, kriegsman@tr.org (Mark
> Has anyone every actually written code that create AE object specifiers
> that use the formTest / typeObjectBeingExamined business in C or C++?
Mark,
I actually don't think I've seen this either, but there is a solution.
Get my AETracker control panel and install it on your machine.
Restart
Run filemaker pro and the Script Editor
turn AETracker ON (see the docs)
Send the applescript you want to analyze
Turn off AETracker
Go into MPW (or your favorite Text Editor) and open the log file that
AETracker generated
Walk through it, and you'll see both exactly how the Script Editor built
the event, but also how FileMaker parsed it. This has been invaluable to
me in understanding what objects and stuff an applicastion specifically is
looking for (standards? Hah!)
CKH
+++++++++++++++++++++++++++
>From gwatts@fnal.fnal.gov (Gordon Watts)
Date: Sun, 17 Dec 1995 05:02:37 -0600
Organization: Brown University
In article <andyb-1512950946560001@kojak.novia.net>, andyb@oasis.novia.net
(Andy Bachorski) wrote:
>
>... Just noticed he (Gordon) replied to your question as well. Wonder why
>he didn't mention this?
>
>Andy B
Because he (Gordon) was very tired when he posted that note and it didn't
even occur to me: that's what happens when I do owl shifts. :-)
Cheers,
Gordon.
--
gwatts@fnal.fnal.gov
+++++++++++++++++++++++++++
>From sample@esltd.com (Don Sample)
Date: Wed, 20 Dec 1995 15:49:28 -0500
Organization: Enerprise Solutions Ltd
In article <kriegsman-1412951156590001@www.tr.org>, kriegsman@tr.org
(Mark>Kriegsman) wrote:
>Summary:
>
> Has anyone every actually written code that create AE object specifiers
> that use the formTest / typeObjectBeingExamined business in C or C++?
>
>
>I've read IM Interapplication Communication from cover to cover, and
>in general I'm a patient person and I sometimes have a clue; but somebody
>has decided that this week it's my turn to go nuts for a little while...
>
The latest issue of d e v e l o p may help you. It has an article on the
opposite end of your problem...the processing of "whose" apple events.
Maybe seeing how one is taken appart will tell you how to put one
together.
--
Don Sample (sample@esltd.com) | Quando Omni Flunkus
Enterprise Solutions Ltd. | Moritati
http://www.esltd.com/esl_people/sample/ |
+++++++++++++++++++++++++++
>From wombat@claris.com (Scott Lindsey)
Date: Thu, 21 Dec 1995 16:52:29 -0800
Organization: Claris Corp., Vancouver WA
In article <kriegsman-1412951156590001@www.tr.org>, kriegsman@tr.org (Mark
Kriegsman) wrote:
>Summary:
>
> Has anyone every actually written code that create AE object specifiers
> that use the formTest / typeObjectBeingExamined business in C or C++?
>
>
>I've read IM Interapplication Communication from cover to cover, and
>in general I'm a patient person and I sometimes have a clue; but somebody
>has decided that this week it's my turn to go nuts for a little while...
>
>I'm converting an applescript widget to C, and I've got everything else
>working fine EXCEPT for the "whose" clause, which IMIAC describes in some
>detail as using the formTest / typeObjectBeingExamined coupling. I think
>I'm doing it just like the book shows (don't we all think this?), but I
>just can't get back any useful result from the target app.
To see just what you're getting, try sending the events to yourself with
the kAEDontExecute flag set, and record it with your favorite script
editor. This will generate the canonical AppleScript for the AppleEvent
that you sent.
Here's some pidgen code that corresponds to what works for me. This
particular example generates
every dbRecord of document 1 whose visible is true
which probably isn't particularly valid for FileMaker, but hey, this is
just an example.
OSErr BuildWhoseDesc(const AEDesc *container, AEDesc *result)
{
AEDesc testDesc;
// container is something like "document 1 (of null)"
err = BuildTestDesc(&testDesc);
err = CreateObjSpecifier(cDBRecord, container, formTest,
&testDesc, true, result);
return err;
}
OSErr BuildTestDesc(AEDesc *resultForm)
{
OSErr err;
AEDesc opDesc1, opDesc2, tmpDesc;
tmpDesc.descriptorType = typeObjectBeingExamined;
tmpDesc.dataHandle = NIL;
// ... visible ...
err = CreatePropertyDesc(&tmpDesc, pVisible, &opDesc1);
if (!err)
{
Boolean aBool = TRUE;
// ... true ...
err = AECreateDesc(typeBoolean, &aBool, sizeof(Boolean), &opDesc2);
if (!err)
{
// ... visible is true ...
err = CreateCompDescriptor(kAEEquals, &opDesc1, &opDesc2,
true, resultForm);
}
}
return err;
}
--
Scott Lindsey <wombat@claris.com, wombat@apple.com>
---------------------------
>From Tom Santos <tom@apple.com>
Subject: From FSSpec to DirID
Date: 20 Dec 1995 08:27:39 GMT
Organization: Apple Computer, Inc.
Here's my scenario:
I have an FSSpec of a directory named Stuff
I have a file called Neato.
Neato is located in Stuff.
I want to make an FSSpec of Neato.
I'm looking for a sane way of doing this.
I figure that if I could get the DirID of Stuff, I could
easily make an FSSpec of Neato.
Getting the DirID of Stuff is non-trivial.
Help. I'm losing my mind.
-Tom-
+++++++++++++++++++++++++++
>From Patrick.Stadelmann@etudiants.unine.ch (Patrick Stadelmann)
Date: Wed, 20 Dec 1995 11:33:06 +0100
Organization: University of Neuchatel
In article <4b8hdr$mse@apple.com>, Tom Santos <tom@apple.com> wrote:
> Here's my scenario:
>
> I have an FSSpec of a directory named Stuff
> I have a file called Neato.
> Neato is located in Stuff.
> I want to make an FSSpec of Neato.
>
> I'm looking for a sane way of doing this.
>
> I figure that if I could get the DirID of Stuff, I could
> easily make an FSSpec of Neato.
>
> Getting the DirID of Stuff is non-trivial.
>
> Help. I'm losing my mind.
1) Get MoreFiles (from DTS sample code). It has a routine to get
the DirID from a FSSpec
2) You can call FSMakeFSSpec with volRef and parent IDfrom the FSSpec
of Stuff, and name set to "\p:Stuff:Neato"
Hope this helps
Patrick
--
Patrick Stadelmann <Patrick.Stadelmann@etudiants.unine.ch>
+++++++++++++++++++++++++++
>From jimm@io.com (Jim Menard)
Date: 20 Dec 1995 21:57:05 GMT
Organization: Completely un-
In article <4b8hdr$mse@apple.com> Tom Santos <tom@apple.com> writes:
I have an FSSpec of a directory named Stuff
I have a file called Neato.
Neato is located in Stuff.
I want to make an FSSpec of Neato.
Pretty easy. Just append the string ":Neato" to the file spec's name, like
this (UNTESTED CODE ALERT):
FSSpec stuffFileSpec;
// Fill in stuffFileSpec; you said you already have this.
FSSpec neatoFileSpec = stuffFileSpec;
CopyPStr(neatoFileSpec, "\p:Neato", sizeof(neatoFileSpec.name));
// Voila!
Jim
--
Jim Menard jimm@io.com http://www.io.com/~jimm/ Be, Inc. "Hairy Guy"
"Is 'anal-retentive' hyphenated?" -- Tech Writer (reported by Richard Wesley)
+++++++++++++++++++++++++++
>From browning@cu-online.com (Dr. Benway)
Date: Thu, 21 Dec 1995 09:55:17 -0600
Organization: Interzone
In article <4b8hdr$mse@apple.com>, Tom Santos <tom@apple.com> wrote:
> Here's my scenario:
>
> I have an FSSpec of a directory named Stuff
> I have a file called Neato.
> Neato is located in Stuff.
> I want to make an FSSpec of Neato.
>
> I'm looking for a sane way of doing this.
>
> I figure that if I could get the DirID of Stuff, I could
> easily make an FSSpec of Neato.
>
> Getting the DirID of Stuff is non-trivial.
>
> Help. I'm losing my mind.
>
> -Tom-
Try using PBGetCatInfo.
procedure DirFSSpecToDirID(theSpec:FSSpec; var theDir:LONGINT);
var
theCInfoPBRec: CInfoPBRec;
theName: Str255;
theErr: OSErr;
begin
theName := theSpec.name; { ioNamePtr must be pointer to Str255 }
with theCInfoPBRec do
begin
ioCompletion := NIL;
ioNamePtr := @theName;
ioVRefNum := theSpec.vRefNum;
ioFDirIndex := 0;
ioDrDirID := theSpec.parID;
end;
theErr := PBGetCatInfoSync(@theCInfoPBRec);
if theErr = noErr then
theDir := theCInfoPBRec.ioDrDirID
else
{ handle error here }
end;
That chunk of code should get the job done.
Doc
--
Dr. Benway :::::::::::::::::: Interzone
=======================================
* I can feel the heat closing in... *
=======================================
* browning@cu-online.com *
* http://www.cu-online.com/~browning/ *
=======================================
---------------------------
>From pmth02jc@umassd.edu (Jim Correia)
Subject: Getting the Highlight color as set in the Color Control Panel?
Date: Wed, 20 Dec 1995 09:17:28 -0500
Organization: University of Massachusetts Dartmouth
How do I get the Highlight color as the person has set it in the Color
Control Panel?
Is there a straight forward way to do this?
Is there any way to do this?
Toolbox Assistant hasn't given me the answer...
Jim
--
Jim Correia
Software Developer
SimCalc Project
+++++++++++++++++++++++++++
>From francois-regis.degott@imag.fr (Fr. Degott)
Date: 20 Dec 1995 15:17:21 GMT
Organization: LMC-IMAG
In article <pmth02jc-2012950917440001@10.0.2.15>, pmth02jc@umassd.edu (Jim
Correia) wrote:
> How do I get the Highlight color as the person has set it in the Color
> Control Panel?
>
> Is there a straight forward way to do this?
>
> Is there any way to do this?
>
> Toolbox Assistant hasn't given me the answer...
>
Hi Jim,
the hilite color is defined in low memory, at $0DA0 (RGBColor var.).
the 'old' method is:
const HiliteRGB = $0DA0;
type RGBColorPtr = ^RGBColor;
var HiliteColor: RGBColor;
…
HiliteColor := RGBColorPtr(HiliteRGB)^;
…
the 'new' method is to use the LMGetHiliteRGB() procs.
defined in the LowMem.h (or .p) file (univ. headers).
procedure LMGetHiliteRGB (var hiliteRGBValue: RGBColor);
HTH
Bye
Fr
_____________________________________________________________________________
Fr. Degott (Francois-Regis.Degott@imag.fr)
LogiMath, Lab. LMC-IMAG - Grenoble - France
+++++++++++++++++++++++++++
>From Patrick.Stadelmann@etudiants.unine.ch (Patrick Stadelmann)
Date: Wed, 20 Dec 1995 17:12:54 +0100
Organization: University of Neuchatel
In article <pmth02jc-2012950917440001@10.0.2.15>, pmth02jc@umassd.edu (Jim
Correia) wrote:
> How do I get the Highlight color as the person has set it in the Color
> Control Panel?
>
> Is there a straight forward way to do this?
>
> Is there any way to do this?
>
> Toolbox Assistant hasn't given me the answer...
>From LowMem.h :
pascal void LMGetHiliteRGB(RGBColor *hiliteRGBValue);
Patrick
--
Patrick Stadelmann <Patrick.Stadelmann@etudiants.unine.ch>
+++++++++++++++++++++++++++
>From Matt Slot <fprefect@umich.edu>
Date: 21 Dec 1995 02:47:30 GMT
Organization: University of Michigan
Jim Correia, pmth02jc@umassd.edu writes:
> How do I get the Highlight color as the person has set it in the Color
> Control Panel?
>
> Is there a straight forward way to do this?
>
> Is there any way to do this?
You are probably trying to highlight some text or another screen object,
and want to draw the color yourself. However, the toolbox has simple
support for "doing the right thing" WRT highlighting.
Normally on B/W machines, highlighting involves inverting the afflicted
area with InvertRect()/InvertRgn. On ColorQD machines, you can simply
insert the following line of code just before the Invert:
if (gHasColorQD) LMSetHiliteMode(LMGetHiliteMode() ^ 0x80);
ColorQD automatically checks this lomem global when going to do an Invert
operation, and if it is toggled (not set!) it will paint it with the
highlight color! This is a once only setting, so you need to do it before
each Invert/highlight call.
Enjoy,
Matt
* * * * * * * * * * * * * * * * * * * * * * * * * * ======================
* Reality: Matt Slot * Time is an illusion.
* E-Mail: mailto:fprefect@umich.edu * Lunchtime doubly so.
* Web: http://www.sils.umich.edu/~fprefect/ * -- Douglas Adams
* * * * * * * * * * * * * * * * * * * * * * * * * * ======================
+++++++++++++++++++++++++++
>From chris_page@powertalk.claris.com (Chris Page)
Date: Thu, 21 Dec 1995 16:22:16 -0800
Organization: Claris Corporation
In article <pmth02jc-2012950917440001@10.0.2.15>, pmth02jc@umassd.edu (Jim
Correia) wrote:
> How do I get the Highlight color as the person has set it in the Color
> Control Panel?
As others have noted, you can read the low-memory global variable using
LMGetHiliteRGB(), or, better yet, you can use LMSetHiliteMode() to let
Color QuickDraw do the work of hiliting for you. But also note:
The system hilite color is stored in the low-memory global, but every
color port has its own hilite color variable and can use it to override
the low-memory value (CGrafPort has a handle, grafVars, to a GravVars
struct with a hiliteRGB field). Color QD will read this color from the
color port, not the global. If you want to read the color directly,
instead of using LMSetHiliteMode(), be sure to get the color from the
port, not from LMGetHiliteRGB().
--
Chris Page | Internet junk mail, advertisements,
Claris Corporation | and SPAMs bite...
chris_page@powertalk.claris.com | Cut it out! :-P
Disclaimer: opinions are not necessarily those of my employer
---------------------------
>From kalash@starnine.com (Joe Kalash)
Subject: Help patching NewPtr on PPC?
Date: Thu, 21 Dec 1995 11:08:11 -0800
Organization: StarNine Technologines, Inc.
I was recently trying to track down a memory leak that occured only on a
PowerPC. As "leaks" wasn't being useful, I decided to write my own "stuff"
by patching the memory traps. I should have known better...
The code that follows will cheerfully set the trap, but strange things
then happen:
(1) When called from PowerPC land, I actually get the following arguments
to MyNewPtr:
MyNewPtr(long trapNum,long thing, long baseTrap, Size ByteCount)
That is I get 4 arguments, the first seems to be the specific trap
(NewPtrClear, NewPtrSys, ...) the second I suspect as being the enum of
the trap descriptor, the third seems to be a "base" trap (NewPtr in this
case), and the fourth is actually the ByteCount that I want.
(2) When called from 68k land, I get the byte count in the first argument,
as expected.
The combination is not nice. I suspect that I have the enum that describes
the trap wrong, but I have tried many variations (with kPascalStackBased,
kCStackBased, and the dispatched variations), all to no avail. Can anyone
please tell me what stupidity I am doing? While I have long past found the
leak, I would still like to get this patch to work (I have been able to
patch toolbox calls, without this hassle).
Side whine, WHY do I have to write the enum that describes this trap? WHY
aren't they all in a nice header file supplied by Apple so I don't have to
spend my time dicking with this? I refuese to believe that I am the only
person on Earth who has ever had a need to patch an OS trap.
--
Thanks,
Joe Kalash
StarNine Technologies, Inc.
kalash@starnine.com
# include <Traps.h>
# include <MixedMode.h>
enum {
uppNewPtrTrapInfo = kRegisterBased
| RESULT_SIZE(SIZE_CODE(sizeof(Ptr)))
| REGISTER_RESULT_LOCATION(kRegisterA0)
| REGISTER_ROUTINE_PARAMETER(1, kRegisterD0, SIZE_CODE(sizeof(Size))),
uppNewHandleTrapInfo = kRegisterBased
| RESULT_SIZE(SIZE_CODE(sizeof(Handle)))
| REGISTER_RESULT_LOCATION(kRegisterA0)
| REGISTER_ROUTINE_PARAMETER(1, kRegisterD0, SIZE_CODE(sizeof(Size))),
uppDisposePtrTrapInfo = kRegisterBased
| REGISTER_ROUTINE_PARAMETER(1, kRegisterA0, SIZE_CODE(sizeof(Ptr))),
uppDisposeHandleTrapInfo = kRegisterBased
| REGISTER_ROUTINE_PARAMETER(1, kRegisterA0, SIZE_CODE(sizeof(Handle)))
};
typedef UniversalProcPtr MemoryTrapUPP;
MemoryTrapUPP __NewPtrTrapUPP = nil;
MemoryTrapUPP __OldNewPtrTrap = nil;
Ptr MyNewPtr(Size ByteCount);
Ptr
MyNewPtr(Size ByteCount)
{
Ptr retVal;
retVal = (Ptr)
CallOSTrapUniversalProc(__OldNewPtrTrap,uppNewPtrTrapInfo,ByteCount);
return (retVal);
}
main()
{
__OldNewPtrTrap = (MemoryTrapUPP) NGetTrapAddress(_NewPtr,OSTrap);
__NewPtrTrapUPP = NewRoutineDescriptor((ProcPtr) MyNewPtr,
uppNewPtrTrapInfo, kPowerPCISA);
NSetTrapAddress((UniversalProcPtr) __NewPtrTrapUPP,_NewPtr,OSTrap);
}
+++++++++++++++++++++++++++
>From d88-bli@xbyse.nada.kth.se (Bo Lindbergh)
Date: 22 Dec 1995 01:43:57 GMT
Organization: Royal Institute of Technology, Stockholm, Sweden
In article <kalash-2112951108110001@boris.starnine.com> kalash@starnine.com (Joe Kalash) writes:
[description of horrors experienced while trying to patch an OS trap
natively deleted]
Just about the only way to get this right is to disassemble the glue in
InterfaceLib to see what it does. For NewPtr, it turns out to be this:
mflr r0
stwu SP,-0x0040(SP)
stw r0,0x0048(SP)
ori r6,r3,0x0000
lis r4,0x0003
lis r0,0x0001
addic r4,r4,0x3932
subic r5,r0,0x5EE2
lwz r3,0x0478(r0)
bl CallOSTrapUniversalProc
lwz RTOC,0x0014(SP)
lwz r12,0x0048(SP)
stw r3,0x0038(SP)
mtlr r12
addic SP,SP,0x0040
blr
It calls CallOSTrapUniversalProc with four args:
0x478 is the address of the OS trap table entry for NewPtr,
so the first arg is the trap address for NewPtr.
The second arg is 0x33932, which translates to this procInfo:
kRegisterBased
| REGISTER_RESULT_LOCATION(kRegisterA0)
| RESULT_SIZE(kFourByteCode)
| REGISTER_ROUTINE_PARAMETER(1,kRegisterD1,kFourByteCode)
| REGISTER_ROUTINE_PARAMETER(2,kRegisterD0,kFourByteCode)
The third arg is 0xA11E, the trap value _NewPtr. For a 68k
routine, this goes into register d1 (which fits the calling
convention for OS traps as described in IM).
The fourth arg is the requested size. For a 68k routine,
this goes into register d0 (which fits the parameter pragma
for NewPtr in <Memory.h>).
So a native patch of NewPtr should be declared like this:
Ptr myNewPtr(unsigned long trapWord,Size size);
And the procInfo for its UPP as well as for the call through to
the old version should be this:
kRegisterBased
| REGISTER_RESULT_LOCATION(kRegisterA0)
| RESULT_SIZE(SIZE_CODE(sizeof (Ptr)))
| REGISTER_ROUTINE_PARAMETER(1,kRegisterD1,SIZE_CODE(sizeof (unsigned long)))
| REGISTER_ROUTINE_PARAMETER(2,kRegisterD0,SIZE_CODE(sizeof (Size)))
Repeating the above for NewHandle, DisposePtr, and DisposeHandle is left
as an exercise for the search and replace function of your editor.
> Side whine, WHY do I have to write the enum that describes this trap? WHY
> aren't they all in a nice header file supplied by Apple so I don't have to
> spend my time dicking with this? I refuese to believe that I am the only
> person on Earth who has ever had a need to patch an OS trap.
If Apple told us how to patch OS traps natively, they'd have to
tell us how to patch dispatched toolbox traps natively too, and
_that_ process is too scary to describe on Usenet. :-)
/Bo Lindbergh
---------------------------
>From ericd@ra.nilenet.com (Eric A. Drumbor)
Subject: Is delta copying effective?
Date: Fri, 24 Nov 1995 14:27:11 -0700
Organization: BW Software
I've noticed that some of the more popular games (Hornet for
instance) are using a delta copy mode. That is, the only pixels that are
copied to the screen are the pixels that have changed color from what is
on the screen.
Does this really help? I suppose it must to some degree, but it
seems like an awful lot of checking to see what has changed in the
offscreen pixmap. After all the checking has taken place, and only the
changed (delta) pixels have been copied, it doesn't seem like there would
be much of a speed gain given the amount of checking (memory accesses, and
compares) that take place.
Maybe I have the wrong idea on how to go about this, but it doesn't
seem worthwhile. Does anyone have an opinion on the subject? Please, by
all means, prove me wrong... ;-)
--
"Ah, voice come from cow on wall!"
Eric A. Drumbor
ericd@ra.nilenet.com <http://www.nilenet.com/~ericd/>
BW Software
+++++++++++++++++++++++++++
>From mick@emf.net (Mick Foley)
Date: Fri, 24 Nov 1995 18:47:46 -0800
Organization: "emf.net" Quality Internet Access. (510) 704-2929 (Voice)
In article <ericd-2411951427110001@slip18.nilenet.com>,
ericd@ra.nilenet.com (Eric A. Drumbor) wrote:
> I've noticed that some of the more popular games (Hornet for
> instance) are using a delta copy mode. That is, the only pixels that are
> copied to the screen are the pixels that have changed color from what is
> on the screen.
>
> Does this really help? I suppose it must to some degree, but it
> seems like an awful lot of checking to see what has changed in the
> offscreen pixmap. After all the checking has taken place, and only the
> changed (delta) pixels have been copied, it doesn't seem like there would
> be much of a speed gain given the amount of checking (memory accesses, and
> compares) that take place.
The answer is: Yes it's worth it -- if you have a good way of keeping
track of what has changed and if you are willing to write directly to the
screen (or compose a small number of rects to CopyBits). You are right in
saying that comparing every pixel would be to slow. In flat shaded 3D
games (Hornet, A10, Spectre), one can keep a list of "color runs" and only
change the areas that have changed. In many sprite games, a list of
rectangles that have changed is maintainted and only those rectangles are
copied. A full 640 x 480 screen is 307K, a lot to move. With update rects
or a "color run" list, you can avoid moving most of that data. The savings
more than make up for the time to keep track of the update list.
Mick
+++++++++++++++++++++++++++
>From dwareing@adelaide.on.net (David Wareing)
Date: Sat, 25 Nov 1995 14:58:50 +1100
Organization: Weyland Yutani
In article <ericd-2411951427110001@slip18.nilenet.com>,
ericd@ra.nilenet.com (Eric A. Drumbor) wrote:
> I've noticed that some of the more popular games (Hornet for
>instance) are using a delta copy mode. That is, the only pixels that are
>copied to the screen are the pixels that have changed color from what is
>on the screen.
>
> Does this really help? I suppose it must to some degree, but it
>seems like an awful lot of checking to see what has changed in the
>offscreen pixmap. After all the checking has taken place, and only the
>changed (delta) pixels have been copied, it doesn't seem like there would
>be much of a speed gain given the amount of checking (memory accesses, and
>compares) that take place.
Given Hornet's speed, I'd say that their drawing method is very efficient.
If you disable the debugger, run Hornet and then hit the programmer's
key, then dismiss the dialog, you can see Hornet's updating method in
action. It's very exacting in which pixels get updated. It's surprising
to see just how much *isn't* being changed on the screen each frame...
The brute force method would be to just update the whole window each
frame, but you'd have to think that virtually any decent delta algorithm
could provide speed improvements over that method.
--
David Wareing dwareing@adelaide.on.net
Belair, South Australia http://www.AmbrosiaSW.com/~dwareing/
Macintosh Games & Multimedia Programming
+++++++++++++++++++++++++++
>From songer@lexmark.com
Date: Mon, 27 Nov 1995 14:46:35 GMT
Organization: Lexmark International, Lexington, KY
In article <ericd-2411951427110001@slip18.nilenet.com> ericd@ra.nilenet.com (Eric A. Drumbor) writes:
[...]
Does this really help? I suppose it must to some degree, but it
seems like an awful lot of checking to see what has changed in the
offscreen pixmap. After all the checking has taken place, and only the
changed (delta) pixels have been copied, it doesn't seem like there would
be much of a speed gain given the amount of checking (memory accesses, and
compares) that take place.
[...]
Hi!
Yes it helps. I use edge lists to maintain the update regions of
double buffer to screen. The only downside is that to really get the
best gain one needs a custom blitter that knows about edge lists.
(Read: "not copybits") One can, of course, express edge lists as a
series of rectangles and use CopyBits but depending on the edge list
regions, that can be pretty inefficient.
Anyway,
-Chris
+++++++++++++++++++++++++++
>From albtrssp@crocker.com (Kevin Tieskoetter)
Date: 24 Nov 1995 17:42:15 GMT
Organization: Albatross Productions
In article <ericd-2411951427110001@slip18.nilenet.com>
ericd@ra.nilenet.com (Eric A. Drumbor) writes:
> Does this really help? I suppose it must to some degree, but it
> seems like an awful lot of checking to see what has changed in the
> offscreen pixmap. After all the checking has taken place, and only the
> changed (delta) pixels have been copied, it doesn't seem like there would
> be much of a speed gain given the amount of checking (memory accesses, and
> compares) that take place.
That's where the algorithm is really complicated. I believe they don't
actually check which pixels have changed, but rather do it on a
polygon-oriented level. I believe that it'll always end up copying by
triangles, but I could be wrong.
>
> Maybe I have the wrong idea on how to go about this, but it doesn't
> seem worthwhile. Does anyone have an opinion on the subject? Please, by
> all means, prove me wrong... ;-)
>
It's very worthwhile, look at Hellcats - ran in full-screen 256-colors
on my old 16 Mhz '020 LC. However, I would imagine that as you get more
polygons in the database, it'll quickly slow down. It'll also not work
with texture-mapped or goraud-/phong- shaded polygons, since the same
color does not hold across the entire polygon. Therefore, it'll drop
out of use as machines get faster and games get more complex.
-kevin
//---------------------------------------------------------------------
Kevin Tieskoetter / Software Prestidigitator, Specular International
//---------------------------------------------------------------------
+++++++++++++++++++++++++++
>From jmunkki@beta.hut.fi (Juri Munkki)
Date: 28 Nov 1995 15:03:21 GMT
Organization: Helsinki University of Technology
In article <49505n$nuh@dns.crocker.com> albtrssp@crocker.com (Kevin Tieskoetter) writes:
>That's where the algorithm is really complicated. I believe they don't
>actually check which pixels have changed, but rather do it on a
>polygon-oriented level. I believe that it'll always end up copying by
>triangles, but I could be wrong.
I think you are wrong about the triangles. I would expect that they get
a run length encoded data stream out from a scan converter, which they
then compare with what is currently shown on the screen. YX-P scan
converters are quite well understood and the algorithms can be found
in basic 3D computer graphics textbooks.
>It's very worthwhile, look at Hellcats - ran in full-screen 256-colors
>on my old 16 Mhz '020 LC. However, I would imagine that as you get more
>polygons in the database, it'll quickly slow down. It'll also not work
>with texture-mapped or goraud-/phong- shaded polygons, since the same
>color does not hold across the entire polygon. Therefore, it'll drop
>out of use as machines get faster and games get more complex.
It depends on how you define "not work". You still only draw each pixel
once with this method, if you do decide to do texture maps.
You are right about the polygon counts though, but on the PPC scan
conversion runs very quickly in the cache, since the algorithm uses
relatively little memory. This may give new life to the method for a
while, especially since it allows you to avoid unnecessary screen and
texture memory access and texture calculations.
Eventually, it will be replaced by something else, but there's still
life left in it.
--
Juri Munkki jmunkki@iki.fi In cyberspace everyone can hear you scream.
http://www.iki.fi/~jmunkki Windsurfing: Faster than the wind.
+++++++++++++++++++++++++++
>From phixus@deltanet.com (Chris De Salvo)
Date: Tue, 28 Nov 1995 08:44:40 -0800
Organization: MacPlay
In article <ericd-2411951427110001@slip18.nilenet.com>,
ericd@ra.nilenet.com (Eric A. Drumbor) wrote:
> I've noticed that some of the more popular games (Hornet for
>instance) are using a delta copy mode. That is, the only pixels that are
>copied to the screen are the pixels that have changed color from what is
>on the screen.
>
> Does this really help? I suppose it must to some degree, but it
>seems like an awful lot of checking to see what has changed in the
>offscreen pixmap. After all the checking has taken place, and only the
>changed (delta) pixels have been copied, it doesn't seem like there would
>be much of a speed gain given the amount of checking (memory accesses, and
>compares) that take place.
Normally what you do is divide the screen into sections. Maybe 32x32
blocks or something. Whenever you draw something on the screen you figure
out which of those bocks are overlapped by the new graphics and you mark
those blocks at dirty. Then, when it's time to update the screen you just
check your dirty-rectangle map and only update those blocks.
Doing a pixel-for-pixel compare would be MUCH too painful.
L8R
Chris
--
phixus@deltanet.com | Macintosh: Changing the world,
Chris De Salvo | one person at a time!
Professional Mac Geek | -----------------------------
for MacPlay, Inc. | (I wish they'd hurry up!)
http://www.deltanet.com/users/phixus
+++++++++++++++++++++++++++
>From ajbarry@ozemail.com.au (Andrew Barry)
Date: Sat, 02 Dec 1995 11:37:08 +1000
Organization: OzEmail Pty Ltd - Australia
> I've noticed that some of the more popular games (Hornet for
> instance) are using a delta copy mode. That is, the only pixels that are
> copied to the screen are the pixels that have changed color from what is
> on the screen.
>
> Does this really help? I suppose it must to some degree, but it
> seems like an awful lot of checking to see what has changed in the
> offscreen pixmap. After all the checking has taken place, and only the
> changed (delta) pixels have been copied, it doesn't seem like there would
> be much of a speed gain given the amount of checking (memory accesses, and
> compares) that take place.
>
> Maybe I have the wrong idea on how to go about this, but it doesn't
> seem worthwhile. Does anyone have an opinion on the subject? Please, by
> all means, prove me wrong... ;-)
It depends - while your universe is comprised of large flat-shaded
polygons,then it's worth it.
If you want to take the next step, and start having fairly detailed
worlds, then delta copying becomes inefficient.
ie Becoming dependant on delta-copying can restrict the level of detail in
your game.
If you don't mind losing the bottom end of the market, you can get far
more impressive screens with delta-copying.
Andrew Barry
+++++++++++++++++++++++++++
>From jinjur@kudonet.com (john calhoun)
Date: 3 Dec 1995 06:17:27 GMT
Organization: Scheherazade Software
> In article <ericd-2411951427110001@slip18.nilenet.com>,
> ericd@ra.nilenet.com (Eric A. Drumbor) wrote:
>
> > I've noticed that some of the more popular games (Hornet for
> > instance) are using a delta copy mode. That is, the only pixels that are
> > copied to the screen are the pixels that have changed color from what is
> > on the screen.
> >
> > Does this really help? I suppose it must to some degree, but it
It's a phenomenal speed improvement (we got 100% or more of an increase
when I was helping with the original ZOA).
That said though, for simulator-type games, it's quickly becoming a relic
(perhaps to be lodged away with character-graphics). No offense to A-10
and such, but when you move away from flat-shaded polygons and go to rich
texture-mapping, "delta copying" is of no speed benefit (in fact it will
slow you down). So, if flat-shaded polygons is where you're headed,
invest6igate this, but if you're going toward texture-mapping, forget it.
john calhoun-
+++++++++++++++++++++++++++
>From jinjur@kudonet.com (john calhoun)
Date: 6 Dec 1995 04:12:32 GMT
Organization: Scheherazade Software
In article <49505n$nuh@dns.crocker.com>, albtrssp@crocker.com (Kevin
Tieskoetter) wrote:
> In article <ericd-2411951427110001@slip18.nilenet.com>
> ericd@ra.nilenet.com (Eric A. Drumbor) writes:
>
> That's where the algorithm is really complicated. I believe they don't
> actually check which pixels have changed, but rather do it on a
> polygon-oriented level. I believe that it'll always end up copying by
> triangles, but I could be wrong.
Yes and no and sort of. Yes, you're right, they don't check every pixel,
but no they don't do it at the polygon level per se. (And it's sort of
complicated.)
They do it at the scanline level (so, sort of the sub-polygon level).
It's done by maintaining a run-length encoded (RLE) array for each
scanline on the screen. It's a good deal quicker to traverse a RLE array
to determine what's changed than every pixel.
BTW, if you ever cheated (hacked) Hellcats so that you could get 100's of
rockets, it was possible to launch such a volley of rockets that the
resulting explosions (and their myriad of little polygons) caused the RLE
scheme to come down to it's knees (and I believe we even crashed the game
a few times).
john calhoun-
+++++++++++++++++++++++++++
>From dwareing@adelaide.on.net (David Wareing)
Date: Thu, 14 Dec 1995 17:57:00 +0930
Organization: Weyland Yutani
In article <jinjur-0512952010200001@165.227.52.137>, jinjur@kudonet.com
(john calhoun) wrote:
>BTW, if you ever cheated (hacked) Hellcats so that you could get 100's of
>rockets, it was possible to launch such a volley of rockets that the
>resulting explosions (and their myriad of little polygons) caused the RLE
>scheme to come down to it's knees (and I believe we even crashed the game
>a few times).
I suspect the crash may have been a result of running out of memory,
thanks to all the extra rockets, rather than a problem with the
rendering scheme. When I pumped up Hellcat's memory allocation, the
crashes did not occur, and everything seemed to be getting drawn ok,
even with scads of rockets and explosions all over the place. Of
course, it was as slow as molasses though.
[your kilometerage may vary]
--
David Wareing dwareing@adelaide.on.net
Belair, South Australia http://www.AmbrosiaSW.com/~dwareing/
Macintosh Games & Multimedia Programming
---------------------------
>From Dustin_Mitchell@onf.com (Dustin J. Mitchell)
Subject: NBP Lookups
Date: 19 Dec 1995 18:37:08 GMT
Organization: Internet Maine Inc.
Can anyone explain just how the real-time background lookups are
accomplished by stuff like Chooser and most games?? When another user
comes onto the network, the code picks up the new entity pretty quickly
and throws it on the list. How is this done?
Also, is it still considered acceptable to use DDP routines for speedy
communication (i.e. video game)
Please reply in email--I'll post results here.
Thanx..
DustyM
+++++++++++++++++++++++++++
>From jumplong@aol.com (Jump Long)
Date: 22 Dec 1995 02:39:27 -0500
Organization: America Online, Inc. (1-800-827-6364)
Dustin J. Mitchell wrote:
>Can anyone explain just how the real-time background lookups are
>accomplished by stuff like Chooser and most games?? When another
>user comes onto the network, the code picks up the new entity
>pretty quickly and throws it on the list. How is this done?
They do it by calling PLookupName asynchronously and then look at the
NBPnumGotten field to catch new matches as they are returned. Here's a
short example that shows how it's done.
- Jim Luther
- ---
#include <Memory.h>
#include <AppleTalk.h>
#include <StdIO.h>
#include <Files.h>
enum
{
kTupleSize = 104, /* sizeof(AddrBlock) + a one-byte enumerator +
sizeof(EntityName) */
kStartMatches = 20, /* Approximate number of matches to get to
start with */
kInterval = 0x0f, /* Reasonable starting place for interval... */
kCount = 0x03 /* ...and count */
};
void main(void)
{
OSErr result;
MPPParamBlock mppPB;
short lookupAttempt;
Ptr returnBufferPtr;
EntityName lookupEntity, matchEntity;
Str32 entityObject = "\p="; /* find any object */
Str32 entityType = "\pAFPServer"; /* find AppleShare servers
*/
Str32 entityZone = "\p*"; /* in the current zone */
short entityCount = kStartMatches; /* The maximum number of
matches
we'd like */
short interval = kInterval;
short count = kCount;
short currentCount, oldCount;
Boolean done;
short index;
AddrBlock entityAddress;
for (lookupAttempt = 1; lookupAttempt <= 5; ++lookupAttempt)
{
printf("Start Lookup #%d\n",lookupAttempt);
/* Allocate buffer for replies */
returnBufferPtr = NewPtr((Size) entityCount * (Size) kTupleSize);
if ( returnBufferPtr != NULL )
{
/* Create a packed entity name */
NBPSetEntity((Ptr) &lookupEntity, entityObject, entityType,
entityZone);
oldCount = 0;
/* ioRefNum and csCode are filled in by PLookupName's glue */
mppPB.MPPioCompletion = nil; /* polling for completion
*/
mppPB.NBPinterval = interval; /* Reasonable values for
the interval */
mppPB.NBPcount = count; /* and retry count */
mppPB.NBPentityPtr = (Ptr) &lookupEntity; /* The entity name to
look for */
mppPB.NBPretBuffPtr = returnBufferPtr; /* Where the reply tuples
will go */
mppPB.NBPretBuffSize = (entityCount) * (Size) kTupleSize;
/* Return buffer size */
mppPB.NBPmaxToGet = entityCount; /* The number of entities
the
return buffer can hold
*/
result = PLookupName(&mppPB, true); /* Lookup the entity name
asynchronously */
if ( result == noErr ) /* the request was delivered to the driver */
{
done = false;
do
{
/* Extract the matches as they come in and
add them to the match list */
done = (mppPB.MPPioResult <= noErr); /* is this the last time
through? */
if ( mppPB.NBPnumGotten > oldCount ) /* anything new to
display? */
{
/* yes, so display them */
currentCount = mppPB.NBPnumGotten;
for ( index = (oldCount + 1); index <= currentCount; ++index)
{
if ( NBPExtract(returnBufferPtr, currentCount, index,
&matchEntity, &entityAddress) == noErr )
{
printf("%08lx %#s:%#s@%#s\n", entityAddress,
matchEntity.objStr, matchEntity.typeStr,
matchEntity.zoneStr);
}
}
oldCount = currentCount;
}
} while ( !done );
}
if ( entityCount <= mppPB.NBPnumGotten )
entityCount += 20; /* get more next time */
DisposPtr(returnBufferPtr); /* Give space back */
}
printf("Finish Lookup #%d\n",lookupAttempt);
}
}
- ---
---------------------------
>From Dwight Kelly <dkelly@etsinc.com>
Subject: PICT opcode $9a?
Date: Wed, 20 Dec 1995 12:29:31 -0500
Organization: Essential Technical Services, Inc.
Does anyone have information on opcode $9a in a PICT2 resource?
Inside Macintosh volume 5 lists it as a reserved opcode, however,
most applications including photoshop store their 16 and 32 bit
PICT previews using $9a.
--
Dwight Kelly
Essential Technical Services, Inc.
110 Industrial Park Drive Suite A-2 Cumming, GA 30130
voice:(770) 889-2848 fax:(770) 889-2624 Internet:dkelly@etsinc.com
http://www.etsinc.com
+++++++++++++++++++++++++++
>From devon@apple.com (Devon Hubbard)
Date: Wed, 20 Dec 1995 17:18:57 -0800
Organization: Apple Computer
In article <30D847FB.27E9C277@etsinc.com>, Dwight Kelly
<dkelly@etsinc.com> wrote:
> Does anyone have information on opcode $9a in a PICT2 resource?
>
> Inside Macintosh volume 5 lists it as a reserved opcode, however,
> most applications including photoshop store their 16 and 32 bit
> PICT previews using $9a.
OpCode 0x9A is 'Direct CopyBits Rectangle' It differs slightly from
OpCode 0x90 (CopyBits Rectangle) in that 0x9A can specify more details
like pixel size, type, horiz/vertical resolutions, and bit packing. IM5
is pretty useless these days huh? I tried to find reference to it in
'Imaging with Quickdraw' with no luck either. Bummer.
The actual data, if you're trying to pull it apart in existing pictures is
easily viewable with Resorcerer's PICT built-in editor. He (Doug) has
kept pretty up to date on things like that. If you don't have Resorcerer,
it looks like now's a good time to get it. :-)
dEVoN
+++++++++++++++++++++++++++
>From Dwight Kelly <dkelly@etsinc.com>
Date: Thu, 21 Dec 1995 11:24:17 -0500
Organization: MindSpring Enterprises
On Wed, 20 Dec 1995, Devon Hubbard wrote:
> > Does anyone have information on opcode $9a in a PICT2 resource?
> >
> OpCode 0x9A is 'Direct CopyBits Rectangle' It differs slightly from
> OpCode 0x90 (CopyBits Rectangle) in that 0x9A can specify more details
> like pixel size, type, horiz/vertical resolutions, and bit packing. IM5
> is pretty useless these days huh? I tried to find reference to it in
> 'Imaging with Quickdraw' with no luck either. Bummer.
I finally found a description in 'Imaging with Quickdraw' in Appendix A on
pages A-14 and A-15.
- -
Dwight Kelly
Essential Technical Services, Inc.
110 Industrial Park Drive Suite A-2 Cumming, GA 30130
voice:(770) 889-2848 fax:(770) 889-2624 Internet:dkelly@etsinc.com
http://www.etsinc.com
---------------------------
>From rik@astro.psu.edu (Ron Kollgaard)
Subject: Parameter Block woes
Date: 13 Dec 1995 15:03:16 GMT
Organization: Dept. of Astronomy and Astrophysics, The Pennsylvania State University
Okay, this is almost certainly a fit of cluelessness on my part but I'm
having trouble using some of the File Manager calls, even something simple
like PBGetVol() I can pass a ParamBlkPtr to PBGetVol(), but it doesn't
seem to work right since I can't initialize the ioCompletion pointer in
the ParamBlkPtr structure. CW complains that ioCompletion isn't a
member of the data structure. I *can* get File Manager routines that use
CInforPBRec to work (using things like cpbPtr->hFileInfo.ioCompletion = NIL )
but it doesn't seem to work for a ParamBlkPtr.
I'm either missing something really simple here, or it has something to do
with the ParamBlockRec being defined as a union in the header files?
Anyway, how does one initilize the ioCompletion bit of a ParamBlkPtr?
thanks!
Ron
rik@astro.psu.edu
+++++++++++++++++++++++++++
>From cameron_esfahani@powertalk.apple.com (Cameron Esfahani)
Date: Wed, 13 Dec 1995 12:53:21 -0800
Organization: Apple Computer, Inc.
The trick to understanding how HFS parameter blocks work, is to realize
that all of the similar fields in all of the parameter blocks are at the
same offset. So, to use your example of PBGetVol(), allocate a
VolumeParam block on the stack:
VolumeParam volPB;
OSErr theErr;
volPB.ioCompletion = nil;
theErr = PBGetVol((ParmBlkPtr) &volPB);
Hope this helps,
Cameron Esfahani
---------------------------
>From cshehadi@panix.com (Charles Shehadi)
Subject: Pixel manipulation
Date: Sun, 17 Dec 1995 16:42:54 -0400
Organization: PANIX Public Access Internet and Unix, NYC
Hello..
I'm writing a simple image processing application. I'd like be able to do
some calculations on my image pixel by pixel. My first try at doing this
is:
1. with nested for loops
2. calling GetCPixel(h, v, &temp), then
3. doing the calculations on the red, green, and blue componenents of
temp, and 4. calling SetCPixel(h,v,&temp).
This works but it's really slow. Is there a faster way? Should I bypass
using GetCPixel and SetCPixel and deal with the Window's PixMap directly?
How would iterate through the image?
Any ideas would help...
-Charlie
+++++++++++++++++++++++++++
>From ckt@best.com (Chris Thomas)
Date: Sun, 17 Dec 1995 20:46:12 -0800
Organization: Echo Software
In article <cshehadi-1712951642540001@cshehadi.dialup.access.net>,
cshehadi@panix.com (Charles Shehadi) wrote:
> Hello..
>
> I'm writing a simple image processing application. I'd like be able to do
> some calculations on my image pixel by pixel. My first try at doing this
> is:
>
> 1. with nested for loops
> 2. calling GetCPixel(h, v, &temp), then
> 3. doing the calculations on the red, green, and blue componenents of
> temp, and 4. calling SetCPixel(h,v,&temp).
>
>
> This works but it's really slow. Is there a faster way? Should I bypass
> using GetCPixel and SetCPixel and deal with the Window's PixMap directly?
Yes.
> How would iterate through the image?
Put the image in a GWorld and do something like:
(scuse my psuedocode)
LockPixels(gWorld)
for(gWorld->portPixMap.rowBytes/ the height of gWorld->portPixMap)
for(gWorld->portPixMap.rowBytes)
MyDoSomethingWithPixel(
gWorld->portPixMap->baseAddr[currentRowByte * currentHeight]);
}
UnlockPixels(gWorld)
BlitToMyWindow(gWorld)
Check out the relevant docs for PixMap and GWorld in MPTA, somewhere
at http://dev.info.apple.com. The exact format of a pixel varies
according to the current screen depth- if you can guarantee that
you're using a direct color (>=16 bit depth) device, portPixMap->baseAddr
points to an array of RGBColor.
And don't forget that portPixMap->baseAddr is a handle when using
GWorlds.
--
Chris Thomas, ckt@best.com
+++++++++++++++++++++++++++
>From erichsen@pacificnet.net (Erichsen)
Date: 18 Dec 1995 09:59:35 GMT
Organization: Disorganized
In article <cshehadi-1712951642540001@cshehadi.dialup.access.net>,
cshehadi@panix.com (Charles Shehadi) wrote:
>This works but it's really slow. Is there a faster way? Should I bypass
>using GetCPixel and SetCPixel and deal with the Window's PixMap directly?
>How would iterate through the image?
Get the Develop Article Drawing in GWorlds for Speed and Versatility. It
goes thru the process of making a custom routine to get and set a pixel
that's 624X faster than QuickDraw. It has a lot of other good stuff too.
+++++++++++++++++++++++++++
>From s868672@umslvma.umsl.edu (Tracy Findley)
Date: Mon, 18 Dec 1995 16:32:34 -0600
Organization: University of Missouri - St. Louis
In article <cshehadi-1712951642540001@cshehadi.dialup.access.net>,
cshehadi@panix.com (Charles Shehadi) wrote:
>Hello..
>
>I'm writing a simple image processing application. I'd like be able to do
>some calculations on my image pixel by pixel. My first try at doing this
>is:
>
>1. with nested for loops
>2. calling GetCPixel(h, v, &temp), then
>3. doing the calculations on the red, green, and blue componenents of
>temp, and 4. calling SetCPixel(h,v,&temp).
>
>
>This works but it's really slow. Is there a faster way? Should I bypass
>using GetCPixel and SetCPixel and deal with the Window's PixMap directly?
>How would iterate through the image?
>
>
>Any ideas would help...
>
>-Charlie
Hi!
develop - Issue 10 has an article "Drawing in GWorlds for Speed and
Versatility" that describes in disgusting detail how to properly avoid
GetCPixel and SetCPixel for fantastic speed boosts. In their example they
took a high level routine that took 10.4 seconds to run and whittled it
down 1/60th of a second; and they stopped there because they didn't want
to get into assembly!
I tried to find the URL (I know it's on Apple's web site somewhere) but
they busy, just look around under "Developer Services."
Hope this helps,
David Findley
s868672@umslvma.umsl.edu
Tracy Findley
s868672@umslvma.umsl.edu
+++++++++++++++++++++++++++
>From Binky the Wonderwhorse <binky@mmcorp.com>
Date: 19 Dec 1995 01:45:11 GMT
Organization: MultiMedia Corporation
lo,
>>2. calling GetCPixel(h, v, &temp),
Aaargh, SLOOOW!
>>calling SetCPixel(h,v,&temp).
Same again...Aaargh, SLOOOW!
>>Is there a faster way?
Yup (read on)
>>disgusting detail
but excellent nonetheless
>>they didn't want to get into assembly!
they did use assembly...check out routine FastGWSet32Pixel at the bottom
of page 66 in may 1992s copy of develop. Strangely enough, its 680x0
assembly...I think they meant rewriting all other other routines in
assembly (the FastSetPixel and FastGetPixel were in assembly I believe).
>>LockPixels(gWorld)
>>for(gWorld->portPixMap.rowBytes/ the height of gWorld->portPixMap)
>> for(gWorld->portPixMap.rowBytes)
>> MyDoSomethingWithPixel(
>> gWorld->portPixMap->baseAddr[currentRowByte * currentHeight]);
>>}
>>UnlockPixels(gWorld)
>>BlitToMyWindow(gWorld)
err....wheres your refs to rowBytes? (which is rather important and
easily missed)
Sheesh, if you want something done properly then ya gotta do it yerself.
Look, heres a *simple* routine for mirroring an image (horiz flip
effect). It will flip a GWorld in 8, 16 or 32 bit. (sorry, I only work
in colour)
It shows VERY VERY SIMPLY how to directly access pixels in a bitmap.
Just copy and paste this into your app code...get a picture, draw it into
a gworld, call the mirror routine and then blit your gworld onto the
screen.
The routine is pretty fast but could easily be enhanced. (use longs for
pixel transfers on 8 and 16 bit for 4 and 2 times the speed for
instance...code it in assembly...etc etc)
Hope this makes things a little more clear for you.
Binky
ps. any problems/questions then email me
pps. i think the 0x3FFF should be 0x7FFF...offhand I forget (so sorry)
mail: binky@mmcorp.com
www: http://www.mmcorp.com/~binky
//
- ---------------------------------------------------------------------
- ----------
// • MirrorGWorld
//
- ---------------------------------------------------------------------
- ----------
// Mirror horizontal code that calls the appropriate mirror code
depending upon bit depth
void
MirrorGWorld(GWorldPtr &sourceGWorld)
{
PixMapHandle sourcePixMap = NULL;
char mode = true32b;
long sourceBase, sourceRowBytes, xMax, yMax;
GWorldPtr destGWorld = NULL;
sourcePixMap = GetGWorldPixMap(sourceGWorld);
LockPixels(sourcePixMap);
sourceBase = (long) GetPixBaseAddr(sourcePixMap) ;
sourceRowBytes = (**sourcePixMap).rowBytes & 0x3FFF; /* ignore garbage
top 2 bits */
yMax = sourceGWorld->portRect.bottom;
xMax = sourceGWorld->portRect.right;
SwapMMUMode(&mode);
switch( (**sourcePixMap).pixelSize )
{
case 8:
Mirror8Bit(sourceBase, sourceRowBytes, xMax, yMax);
break;
case 16:
Mirror16Bit(sourceBase, sourceRowBytes, xMax, yMax);
break;
case 32:
Mirror32Bit(sourceBase, sourceRowBytes, xMax, yMax);
break;
default:
break;
}
SwapMMUMode(&mode);
UnlockPixels(sourcePixMap);
}
//
- ---------------------------------------------------------------------
- ----------
// • Mirror8Bit
//
- ---------------------------------------------------------------------
- ----------
// mirror an 8 bit image horizontally
void
Mirror8Bit(long sourceBase, long sourceRowBytes, long xMax, long yMax)
{
register char columnSplit, rowLoop, columnLoop;
register char *leftPixel, *rightPixel, tempPixel;
columnSplit = (xMax >> 1); // xMax >> 1 = Trunc(xMax / 2)
for (rowLoop = 0; rowLoop < yMax; rowLoop++)
{
leftPixel = (char*)(sourceBase + (rowLoop*sourceRowBytes));
rightPixel = (char*)(leftPixel + xMax -1);
for (columnLoop = columnSplit; columnLoop; columnLoop--)
{
tempPixel = *leftPixel;
*leftPixel++ = *rightPixel;
*rightPixel-- = tempPixel;
}
}
}
//
- ---------------------------------------------------------------------
- ----------
// • Mirror16Bit
//
- ---------------------------------------------------------------------
- ----------
// mirror a 16 bit image horizontally
void
Mirror16Bit(long sourceBase, long sourceRowBytes, long xMax, long yMax)
{
register short columnSplit, rowLoop, columnLoop;
register short *leftPixel, *rightPixel, tempPixel;
columnSplit = (xMax >> 1); // xMax >> 1 = Trunc(xMax / 2)
for (rowLoop = 0; rowLoop < yMax; rowLoop++)
{
leftPixel = (short*)(sourceBase + (rowLoop*sourceRowBytes));
rightPixel = (short*)(leftPixel + xMax -1);
for (columnLoop = columnSplit; columnLoop; columnLoop--)
{
tempPixel = *leftPixel;
*leftPixel++ = *rightPixel;
*rightPixel-- = tempPixel;
}
}
}
//
- ---------------------------------------------------------------------
- ----------
// • Mirror32Bit
//
- ---------------------------------------------------------------------
- ----------
// mirror a 32 bit image horizontally
void
Mirror32Bit(long sourceBase, long sourceRowBytes, long xMax, long yMax)
{
register long columnSplit, rowLoop, columnLoop;
register long *leftPixel, *rightPixel, tempPixel;
columnSplit = (xMax >> 1); // xMax >> 1 = Trunc(xMax / 2)
for (rowLoop = 0; rowLoop < yMax; rowLoop++)
{
leftPixel = (long*)(sourceBase + (rowLoop*sourceRowBytes));
rightPixel = (long*)(leftPixel + xMax -1);
for (columnLoop = columnSplit; columnLoop; columnLoop--)
{
tempPixel = *leftPixel;
*leftPixel++ = *rightPixel;
*rightPixel-- = tempPixel;
}
}
}
---------------------------
>From arnold@lumina.com (Brian Arnold)
Subject: Stupid locked file question
Date: Tue, 19 Dec 1995 13:54:04 -0800
Organization: Lumina Decision Systems, Inc.
Okay, this is a really stupid question, but I've never supported
Finder-locked files before.
The Finder Get Info window has a "Locked" checkbox for files. What do I
call to check that this checkbox is checked for a file I am opening?
I looked at FSpGetFInfo, which returns a name locked bit, but it doesn't
get set by the "Locked" checkbox. I then scanned the Files book of New
Inside Mac, and a lot of functions are capable of returning this error:
fLckdErr -45 File is locked
But my file calls never return this for files that have the "Locked" checkbox.
So what routine do I call, and what bit do I test, to find out whether a
file has been locked in the Get Info window?
- Brian
--
Brian Arnold
Director of Software Development
Lumina Decision Systems, Inc.
http://www.lumina.com/lumina/
+++++++++++++++++++++++++++
>From howlett@netcom.com (Scott Howlett)
Date: Wed, 20 Dec 1995 01:49:31 GMT
Organization: (or lack thereof)
Brian Arnold wrote:
> Okay, this is a really stupid question, but I've never supported
> Finder-locked files before.
...
> So what routine do I call, and what bit do I test, to find out whether a
> file has been locked in the Get Info window?
To lock a file, use FSpSetFLock.
To unlock a file, use FSpRstFLock.
To test a file lock, use this:
OSErr
FSpTestFLock(FSSpec *pSpec, Boolean *pIsLocked)
{
CInfoPBRec pb;
OSErr err;
pb.hFileInfo.ioNamePtr = pSpec->name;
pb.hFileInfo.ioVRefNum = pSpec->vRefNum;
pb.hFileInfo.ioDirID = pSpec->parID;
pb.hFileInfo.ioFDirIndex = 0;
if ((err = PBGetCatInfo(&pb, FALSE)) == noErr)
*pIsLocked = pb.hFileInfo.ioFlAttrib & 1;
return err;
}
- Scott
--
Scott Howlett, howlett@netcom.com
"Probably the earliest fly swatters were nothing more than some sort of
striking surface attached to the end of a long stick."
+++++++++++++++++++++++++++
>From phixus@deltanet.com (Chris De Salvo)
Date: Tue, 19 Dec 1995 21:44:20 -0800
Organization: MacPlay
In article <arnold-1912951354040001@227.rahul.net>, arnold@lumina.com
(Brian Arnold) wrote:
>So what routine do I call, and what bit do I test, to find out whether a
>file has been locked in the Get Info window?
Personally, I'd use PBGetCatInfo() on the file. Then, look at the
ioFlAttrib field of the hFileInfo structure. Bit zero tells you whether
or not the file is locked.
L8R
Chris.
--
phixus@deltanet.com | Macintosh: Changing the world,
Chris De Salvo | one person at a time!
Professional Mac Geek | -----------------------------
for MacPlay, Inc. | (I wish they'd hurry up!)
http://www.deltanet.com/users/phixus
+++++++++++++++++++++++++++
>From erichsen@pacificnet.net (Erichsen)
Date: 21 Dec 1995 10:27:48 GMT
Organization: Disorganized
In article <arnold-1912951354040001@227.rahul.net>, arnold@lumina.com
(Brian Arnold) wrote:
>The Finder Get Info window has a "Locked" checkbox for files. What do I
>call to check that this checkbox is checked for a file I am opening?
Call PBGetCatInfo and check the ioFlAttrib to see if the locked bit is set
(ie. pb.hFileInfo.ioFlAttrib & 0x01 ) != 0) . Also check out MoreFiles,
it's a set of routines written by one of Apple's DTS guys (Jim Luther but,
I think he's at General Magic now). It has a routine in the
MoreFilesExtras.c file called CheckObjectLock/FSpCheckObjectLock that does
exactly what you're asking. Here's the code from MoreFiles:
/*****************************************************************************/
pascal OSErr FSpCheckObjectLock(const FSSpec *spec)
{
return ( CheckObjectLock(spec->vRefNum, spec->parID,
(StringPtr)spec->name) );
/*****************************************************************************/
pascal OSErr CheckObjectLock(short vRefNum,
long dirID,
StringPtr name)
{
CInfoPBRec pb;
Str31 tempName;
OSErr error;
/* Protection against File Sharing problem */
if ( (name == NULL) || (name[0] == 0) )
{
tempName[0] = 0;
pb.hFileInfo.ioNamePtr = tempName;
pb.hFileInfo.ioFDirIndex = -1; /* use ioDirID */
}
else
{
pb.hFileInfo.ioNamePtr = name;
pb.hFileInfo.ioFDirIndex = 0; /* use ioNamePtr and ioDirID */
}
pb.hFileInfo.ioVRefNum = vRefNum;
pb.hFileInfo.ioDirID = dirID;
error = PBGetCatInfoSync(&pb);
if ( error == noErr )
{
/* check locked bit */
if ( (pb.hFileInfo.ioFlAttrib & 0x01) != 0 )
error = fLckdErr;
}
return ( error );
}
---------------------------
>From masc1175@rohan.sdsu.edu (Generic Account 1175)
Subject: Using Enqueue() and Dequeue() for custom-made queues
Date: 14 Dec 95 16:33:19 GMT
Organization: San Diego State University
I've been attempting to use the MacOS EnQueue() and Dequeue() functions
to store items, instead of creating my own queue structure. The IM
OS Queues chapter doesn't say enough about doing this, and the only
example I've been able to find in a book (the "Reminder" program in the
C Mac Programming Primer book) isn't very helpful.
Basically, what I've got is this:
typedef struct
{
short stuff;
short moreStuff;
short junk;
} StuffRecord;
QHdr stuffQueue;
(later)
void EnqueueMyStuff(short x, short y, short z)
{
StuffRecord *myStuff = (StuffRecord *)NewPtr(sizeof(StuffRecord));
myStuff->stuff = x;
myStuff->moreStuff = y;
myStuff->junk = z;
Enqueue((QElemPtr)myStuff,&stuffQueue);
}
This is in imitation of the very brief code snippet in the OS Queues
chapter. It doesn't work--when I get stuff off the queue, the data is
inevitably worthless garbage.
The Primer has a slightly different method, wherein the "StuffRecord"
would have a new field, queue of type QElem. The Enqueue() statement
would then read: Enqueue(&myStuff->queue,&stuffQueue). This doesn't
seem to work either.
What am I doing wrong?
(Oh--I'm using CW 7 on a Performa 638. Not that that is much help, I
suppose.)
-et
--
Ernest S. Tomlinson (masc1175@rohan.sdsu.edu) (et@ugcs.caltech.edu)
- -----------------------------------------------------------------
"LOOK UPON ME! I'LL SHOW YOU THE LIFE OF THE MIND! I WILL SHOW
YOU THE LIFE OF THE MIND!!"
+++++++++++++++++++++++++++
>From Matt Slot <fprefect@umich.edu>
Date: 15 Dec 1995 04:40:36 GMT
Organization: University of Michigan
Generic Account 1175, masc1175@rohan.sdsu.edu writes:
> typedef struct
> {
> short stuff;
> short moreStuff;
> short junk;
> } StuffRecord;
>
> [...]
>
> This is in imitation of the very brief code snippet in the OS Queues
> chapter. It doesn't work--when I get stuff off the queue, the data is
> inevitably worthless garbage.
>
> The Primer has a slightly different method, wherein the "StuffRecord"
> would have a new field, queue of type QElem. The Enqueue() statement
> would then read: Enqueue(&myStuff->queue,&stuffQueue). This doesn't
> seem to work either.
Your struct should be declared like this:
typedef struct
{
QElem *qElem;
short qType;
// Your Data Here
short stuff;
short moreStuff;
short junk;
} StuffRecord;
The Enqueue() and DeQueue() calls expect the first 6 bytes to be
available for management (actually, the qType is only *really*
important for OS-maintained queues).
* * * * * * * * * * * * * * * * * * * * * * * * * * ======================
* Reality: Matt Slot * Time is an illusion.
* E-Mail: mailto:fprefect@umich.edu * Lunchtime doubly so.
* Web: http://www.sils.umich.edu/~fprefect/ * -- Douglas Adams
* * * * * * * * * * * * * * * * * * * * * * * * * * ======================
+++++++++++++++++++++++++++
>From erichsen@pacificnet.net (Erichsen)
Date: 15 Dec 1995 17:47:27 GMT
Organization: Disorganized
In article <masc1175.818958799@rohan>, masc1175@rohan.sdsu.edu (Generic
Account 1175) wrote:
>I've been attempting to use the MacOS EnQueue() and Dequeue() functions
>to store items, instead of creating my own queue structure. The IM
>OS Queues chapter doesn't say enough about doing this, and the only
>example I've been able to find in a book (the "Reminder" program in the
>C Mac Programming Primer book) isn't very helpful.
>
>Basically, what I've got is this:
>
>typedef struct
>{
> short stuff;
> short moreStuff;
> short junk;
>} StuffRecord;
The problem is you aren't giving Enqueue a field to store it's link. The
qLink field is important. Enqueue uses it to keep track of the elements in
the queue.
You need to setup your structure like this:
struct ElementRecord
{
struct ElementRecord *qLink;
short qType;
// Add Your Stuff After the First qLink and qType.
short stuff;
short moreStuff;
short junk;
// Any other stuff you need.
};
typedef struct ElementRecord ElementRecord,
*ElementPtr;
Then you add an element to your custom queue like this:
...
OSErr error;
ElementPtr element;
element = ( ElementPtr ) NewPtrClear( sizeof( ElementRecord ) );
error = MemError();
if( error != noErr ) return( error );
element->stuff = -1;
element->moreStuff = 0;
element->junk = 1;
Enqueue( ( QElemPtr ) element, &gYourCustomQueue );
...
---------------------------
>From David Reiss <reiss@astro.washington.edu>
Subject: [HELP] New to color palettes...simple question!
Date: 1 Dec 1995 21:25:05 GMT
Organization: http://www.astro.washington.edu
Hi. I am trying to create a window which uses a custom palette which
I have created as a resource with 256 slightly different shades of
blue. Here's the simple code after I create the window (hidden, for
the moment)...
PaletteHandle myPalette = GetNewPalette( 1000 );
SetPalette( myWindow, myPalette, TRUE );
Simple enough...but now when my window gets shown on an 8 bit Mac, the
expected shifting of color tables so that everything looks blue does not
occur...in fact, I can draw greens, reds, etc. onto my window. Am I
missing a call, to build an inverse color table, or something? I'd
appreciate any theories. Thanks.
-David
+++++++++++++++++++++++++++
>From heaney@crl.com (John S. Heaney)
Date: 1 Dec 1995 22:06:22 -0800
Organization: CRL Dialup Internet Access (415) 705-6060 [Login: guest]
In article <49nrrh$h5j@nntp5.u.washington.edu>,
David Reiss <reiss@astro.washington.edu> wrote:
>Simple enough...but now when my window gets shown on an 8 bit Mac, the
>expected shifting of color tables so that everything looks blue does not
>occur...in fact, I can draw greens, reds, etc. onto my window. Am I
>missing a call, to build an inverse color table, or something? I'd
>appreciate any theories. Thanks.
Try an ActivatePalette( myWindow );
--
John Heaney Time flies whether you're having fun or not.
heaney@crl.com
+++++++++++++++++++++++++++
>From adamnash@cs.stanford.edu (Adam Nash)
Date: Tue, 05 Dec 1995 04:58:17 -0800
Organization: Computer Science, Stanford University
In article <49oqcu$o1j@crl5.crl.com>, heaney@crl.com (John S. Heaney) wrote:
> >Simple enough...but now when my window gets shown on an 8 bit Mac, the
> >expected shifting of color tables so that everything looks blue does not
> >occur...in fact, I can draw greens, reds, etc. onto my window. Am I
> >missing a call, to build an inverse color table, or something? I'd
> >appreciate any theories. Thanks.
>
> Try an ActivatePalette( myWindow );
>
ActivatePalette is crucial, but you still may run into problems if your
colors are set to tolerant. To be safe, set their tolerance to 0. Note,
this is
really bad style, since the Mac Toolbox *insists* that your first two colors
should be white and black. So try that w/ 254 blues, no tolerance, and
ActivatePalette. Also, Try checking the Advanced Imaging Inside
Macintosh, available on Apple's ftp site.
-Adam
--
Adam Nash
CS 108 TA
adamnash@cs.stanford.edu
http://www-leland.stanford.edu/~smashman
Stanford University - Computer Science
+++++++++++++++++++++++++++
>From jstiles@cello.gina.calstate.edu (John Stiles)
Date: Fri, 15 Dec 1995 06:34:32 GMT
Organization: cello.gina.calstate.edu
In article <adamnash-0512950458170001@gel.stanford.edu>,
adamnash@cs.stanford.edu (Adam Nash) wrote:
>ActivatePalette is crucial, but you still may run into problems if your
>colors are set to tolerant. To be safe, set their tolerance to 0. Note,
I just tackled palettes a few days ago, and another important step is:
SelectWindow( myWindow );
Don't laugh. If you're messing around with 10 windows, each with its own
palette, this instruction determines which palette gets used. So it really
IS important. :) Although when I first put it in, and my code worked, I
was scratching my head as to why... :)
*Stiles
+++++++++++++++++++++++++++
>From David Reiss <reiss@astro.washington.edu>
Date: 18 Dec 1995 23:31:46 GMT
Organization: http://www.astro.washington.edu
Yes, I discovered this as well, and now I got it to work...except when I'm
using my floating windows environment, in which case SelectWindow()
never gets called. Do you, or anyone else, know of a way around this
problem? (It seems when you solve one problem, another one springs up
as a result.)
Thanks.
-David
---------------------------
End of C.S.M.P. Digest
**********************